package io.renren.modules.sp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.renren.common.page.PageData;
import io.renren.common.service.impl.CrudServiceImpl;
import io.renren.common.constant.Constant;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.IOUtils;
import io.renren.common.utils.Result;
import io.renren.common.utils.ZipUtils;
import io.renren.modules.security.user.UserDetail;
import io.renren.modules.sp.dao.*;
import io.renren.modules.sp.dto.SpTeamDTO;
import io.renren.modules.sp.entity.*;
import io.renren.modules.sp.service.SpMatchService;
import io.renren.modules.sp.service.SpTeamService;
import io.renren.modules.security.user.SecurityUser;
import io.renren.modules.sp.service.TAreaService;
import io.renren.modules.sys.dao.SysRoleUserDao;
import io.renren.modules.sys.dto.ParamDto;
import io.renren.modules.sys.service.SysRoleUserService;
import io.renren.modules.sys.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.beans.Transient;
import java.net.URLEncoder;
import java.util.*;

/**
 * 领队
 *
 * @author Mark sunlightcs@gmail.com
 * @since 3.0 2023-04-20
 */
@Service
public class SpTeamServiceImpl extends CrudServiceImpl<SpTeamDao, SpTeamEntity, SpTeamDTO> implements SpTeamService {
    @Autowired
    private SpUserDao spUserDao;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SpTeamDao spTeamDao;
    @Autowired
    private SpTeamUserDao spTeamUserDao;
    @Autowired
    private SysRoleUserDao sysRoleUserDao;
    @Autowired
    private SpMatchService spMatchService;
    @Autowired
    private SpMatchItemDao spMatchItemDao;
    @Autowired
    private SpMatchItemTeamDao spMatchItemTeamDao;
    @Autowired
    private SpTeamNumDao spTeamNumDao;
    @Autowired
    private TAreaService tAreaService;
    @Autowired
    private SpMatchItemTeamUserDao spMatchItemTeamUserDao;
    @Autowired
    private SpTicketDao spTicketDao;

    @Override
    public PageData<Map> queryPage(Map<String, Object> params){
        /**
         * 1. 如果超级管理员查询全部
         * 2. 如果是赛事管理员，查询赛事下的代表队
         * 3. 如果是赛项管理员，查询赛项下的代表队
         */
        //获取当前登录用户
        UserDetail user = (UserDetail) SecurityUtils.getSubject().getPrincipal();
        PageData<Map> page = null;
        String userType = sysUserService.getSysUserType();
        // 9学会管理员
        if(user.getSuperAdmin()==1 || "9".equals(userType)){
            //超级管理员
            page = this.pageQuery(params);
        }else if("1".equals(userType) || "3".equals(userType) || "4".equals(userType)){
            //赛事管理员
            Map map = new HashMap();
            map.put("adminId", user.getId());
            List<SpMatchEntity> list = spMatchService.queryPageByAdmin(map);
            String sql = "(";
            String p = "";
            String c = "";
            for(int i=0; i<list.size(); i++){
                SpMatchEntity spMatchEntity = list.get(i);
                p = spMatchEntity.getProvince();
                c = spMatchEntity.getCity();
                if(i>0){
                    sql += " or ";
                }
                sql += "(";
                if(org.apache.commons.lang.StringUtils.isNotEmpty(p)){
                    if(!"-1".equals(p)){
                        if("650000".equals(p)){
                            sql += " t.province in ('650000','660000')";
                        }else {
                            sql += " t.province = '" + p + "' ";
                        }
                    }
                }
                if(org.apache.commons.lang.StringUtils.isNotEmpty(c)){
                    if(!"-1".equals(c)){
                        sql += " and t.city = '"+c+"' ";
                    }
                }
                sql += ") ";
            }
            sql += ")";
            if(list.size()>0){
                params.put("sql", sql);
            }else{
                params.put("sql", "1=2");
            }
            page = this.pageQuery(params);
        } else if ("2".equals(userType)) {
            //赛项管理员角色：也可以显示代表队列表
            String sql = " t.id in ("
                    + " SELECT mit.team_id from sp_match_item_team mit"
                    + " left join sp_match_item mi on mit.match_item_id = mi.id"
                    + " where mi.admin_id = " + user.getId()
                    + " )";
            params.put("sql", sql);
            page = this.pageQuery(params);
        }

        //循环page，取省市信息
        /*for (Map spTeamDTO : page.getList()) {
            // 获取市
            List<ParamDto> list2 = tAreaService.queryByCode((String) spTeamDTO.get("city"));
            if (list2!=null&&list2.size()>0){
                ParamDto paramDto = list2.get(0);
                spTeamDTO.put("cityName", paramDto.getName());
            }
        }*/
        return page;
    }

    @Override
    public Map<String,Object> queryById(Long id){
        return baseDao.queryById(id);
    }

    @Override
    public QueryWrapper<SpTeamEntity> getWrapper(Map<String, Object> params){
        QueryWrapper<SpTeamEntity> wrapper = new QueryWrapper<>();
        return wrapper;
    }

    //保存代表队
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Map<String,Object>> saveTeam(SpTeamDTO dto) {
        /**
         * 代表队的成员：
         * 领队-1人、副领队-最多3人、
         * 指导老师、选手
         * 验证逻辑：
         * 1、一个领队只能带一个代表队，一个代表队只能一个领队
         */
        //1、验证领队是否已经带队
        /*QueryWrapper<SpTeamUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", dto.getLeaderId());
        wrapper.eq("type", Constant.TeamUserType.ADMIN.getValue());
        SpTeamUserEntity spTeamUserEntity = spTeamUserDao.selectOne(wrapper);
        if (spTeamUserEntity != null) {
            return new Result<Map<String,Object>>().error("该领队已经带队");
        }*/

        // 校验代表队单位名称不能重复
        List<SpTeamEntity> comList = spTeamDao.selectList(new QueryWrapper<SpTeamEntity>()
                .eq("company", dto.getCompany()));
        if(comList!=null && comList.size() > 0){
            return new Result<Map<String,Object>>().error("该单位已有代表队");
        }

        List<SpTeamEntity> teamList = spTeamDao.selectList(new QueryWrapper<SpTeamEntity>()
                .eq("creator", dto.getCreator())
        );
        if(teamList!=null && teamList.size() > 0){
            return new Result<Map<String,Object>>().error("该负责人已有代表队");
        }

        // 校验是否是其他队伍的领队
        List<SpTeamUserEntity> teamUserList = spTeamUserDao.selectList(new QueryWrapper<SpTeamUserEntity>()
                .eq("user_id", dto.getCreator())
                .in("type", "1", "2")
        );
        if(teamUserList!=null && teamUserList.size() > 0){
            return new Result<Map<String,Object>>().error("该负责人已是其他队伍的领队,请先解除");
        }

        //2、验证代表队是否已经有领队
        /*wrapper = new QueryWrapper<>();
        wrapper.eq("team_id", dto.getId());
        wrapper.eq("type", Constant.TeamUserType.LEADER.getValue());
        spTeamUserEntity = spTeamUserDao.selectOne(wrapper);
        if (spTeamUserEntity != null) {
            return new Result<Map<String,Object>>().error("该代表队已经有领队");
        }*/

        //3、查询领队信息
        SpUserEntity leader = spUserDao.selectById(dto.getCreator());
        //保存领队授权书
        if (StringUtils.isNotBlank(dto.getEmpower())) {
            leader.setEmpower(dto.getEmpower());
            spUserDao.updateById(leader);
        }

        //4、保存代表队
        SpTeamEntity spTeamEntity = new SpTeamEntity();
        BeanUtils.copyProperties(dto, spTeamEntity);
        spTeamEntity.setCreateTime(new Date());
        spTeamEntity.setLeader(leader.getRealName());
        spTeamEntity.setPhone(leader.getPhone());
        spTeamEntity.setHeader(leader.getHeader());
        spTeamEntity.setSex(leader.getSex());
        //spTeamEntity.setIdType(Integer.parseInt(leader.getIdType()));
        spTeamEntity.setIdCard(leader.getIdCard());
        spTeamDao.insert(spTeamEntity);

        //修改代表队的编码，规则：5位数字，不足5位前面补0
        String teamCode = String.format("%05d", spTeamEntity.getId());
        spTeamEntity.setTeamCode(teamCode);
        spTeamDao.updateById(spTeamEntity);

        //5、保存领队信息
        SpTeamUserEntity spTeamUserEntity = new SpTeamUserEntity();
        spTeamUserEntity.setTeamId(spTeamEntity.getId());
        spTeamUserEntity.setUserId(dto.getCreator());
        spTeamUserEntity.setType(Constant.TeamUserType.LEADER.getValue());
        spTeamUserEntity.setPhone(leader.getPhone());
        spTeamUserDao.insert(spTeamUserEntity);
        return new Result<Map<String,Object>>();
    }

    //修改代表队
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Map<String,Object>> updateTeam(SpTeamDTO dto){
        //修改代表队信息
        SpTeamEntity spTeamEntity = new SpTeamEntity();
        BeanUtils.copyProperties(dto, spTeamEntity);
        spTeamEntity.setUpdateTime(new Date());
        //代表队负责人id
        spTeamEntity.setCreator(dto.getLeaderId());
        SpUserEntity leader = spUserDao.selectById(dto.getLeaderId());
        if(leader != null){
            spTeamEntity.setLeader(leader.getRealName());
            spTeamEntity.setPhone(leader.getPhone());
            spTeamEntity.setHeader(leader.getHeader());
            spTeamEntity.setSex(leader.getSex());
            spTeamEntity.setIdCard(leader.getIdCard());
        }

        SpTeamEntity teamEntity = spTeamDao.selectById(dto.getId());
        // 判断省市是否修改过
        String province = teamEntity.getProvince();
        String city = teamEntity.getCity();
        //判断省市是否跟传入的值相同
        if(!province.equals(dto.getProvince()) || !city.equals(dto.getCity())) {
            spTeamEntity.setUpdAreaTimes(teamEntity.getUpdAreaTimes() + 1);
            //修改省市时，判断是否有未完赛的选手
            // 2完赛、2的特殊状态-已确认晋级、3未参赛、5特殊状态-放弃晋级、 6晋级成功、7弃权、8驳回 10状态时报名已截 表示完赛
            List<SpMatchItemTeamEntity> userList = spMatchItemTeamDao.selectList(new QueryWrapper<SpMatchItemTeamEntity>()
                    .eq("team_id", dto.getId())
            );
            // 判断是否全部完赛
            boolean flag = true;
            for(SpMatchItemTeamEntity item : userList){
                if (
                        !(
                                item.getStatus() == 2
                                        || (item.getStatus() == 5  && item.getRejectReason() != "放弃晋级")
                                        || item.getStatus() == 3
                                        || item.getStatus() == 7
                                        || item.getStatus() == 8
                                        || item.getStatus() == 6
                                        || item.getStatus() == 10
                        )
                ) {
                    flag = false;
                    break;
                }
            }
            if(!flag) {
                return new Result<Map<String,Object>>().error("该代表队有未完赛的选手，不能修改");
            }
        }
        //代表队名称为空的时候，默认为单位名称
        if(StringUtils.isBlank(dto.getTeamName())){
            spTeamEntity.setTeamName(dto.getCompany());
        }
        spTeamDao.updateById(spTeamEntity);

        // 查询领队
        SpTeamUserEntity teamUserEntity = spTeamUserDao.selectOne(new QueryWrapper<SpTeamUserEntity>()
                .eq("team_id",dto.getId())
                .eq("type",Constant.TeamUserType.LEADER.getValue()));
        if(teamUserEntity != null){
            teamUserEntity.setUserId(dto.getLeaderId());
            teamUserEntity.setPhone(dto.getPhone());
            spTeamUserDao.updateById(teamUserEntity);
        }

        //修改负责人的授权书信息
        SpUserEntity spUserEntity = spUserDao.selectById(spTeamEntity.getCreator());
        if (StringUtils.isNotBlank(dto.getEmpower())) {
            spUserEntity.setEmpower(dto.getEmpower());
            spUserDao.updateById(spUserEntity);
        }

        return new Result<Map<String,Object>>();
    }

    @Override
    public List<SpTeamEntity> queryList(QueryWrapper<SpTeamEntity> params){
        List<SpTeamEntity> list = baseDao.selectList(params);
        return list;
    }


    @Override
    public PageData<Map> pageQuery(Map<String, Object> params){
        Page page = createPage(params);
        //分页参数
        params.put(Constant.PAGE, page);
        IPage<Map<String,Object>> page2 = this.baseDao.pageQuery(page, params);
        PageData<Map> pageData = new PageData(page2.getRecords(),page2.getTotal());
        return pageData;
    }

    @Override
    public Map<String, Object> queryTeamInfo(Long id){
        return baseDao.queryTeamInfo(id);
    }


    @Override
    public List<SpTeamEntity> isExistCompany(String company){
        List<SpTeamEntity> list = spTeamDao.selectList(new QueryWrapper<SpTeamEntity>()
                .eq("company", company)
        );
        return list;
    }

    //判断当前代表队所属省份是否有人数限制
    @Override
    public boolean isLimitNum(Long teamId){
        SpTeamEntity teamEntity = spTeamDao.selectById(teamId);
        if(teamEntity == null){
            return false;
        }
        //查询当前代表队所属省份是否有人数限制
        SpTeamNumEntity spTeamNumEntity = spTeamNumDao.selectOne(new QueryWrapper<SpTeamNumEntity>()
                .eq("province", teamEntity.getProvince())
        );
        // 没有配置，可以报名
        if(spTeamNumEntity == null){
            return true;
        }

        Long num = spTeamUserDao.selectCount(new QueryWrapper<SpTeamUserEntity>()
                .eq("type", Constant.TeamUserType.STUDENT.getValue())
                .eq("team_id", teamId)
        );
        //当前代表队所属省份已报名人数小于限制人数，可报名
        if(num < spTeamNumEntity.getNum()){
            return true;
        }
        return false;
    }


    @Override
    public Map<String, Object> queryTeamInfoByCreator(Long id){
        Map<String, Object> result = new HashMap<>();
         SpTeamEntity entity = baseDao.selectOne(
                 new QueryWrapper<SpTeamEntity>().eq("creator", id)
         );
         if(entity!=null){
             result.put("teamId", entity.getId());
             result.put("teamName", entity.getTeamName());
             result.put("account", entity.getPhone());
             result.put("realName", entity.getLeader());
             result.put("phone", entity.getPhone());
         }
         return result;
    }

    @Override
    public Map<String, Object> queryTeamInfoByPhone(String phone){
        return baseDao.queryTeamInfoByPhone(phone);
    }

    /**
     * 下载承诺书
     *
     * @param
     * @param response
     * @throws Exception
     */
    @Override
    public Result<String> downloadPromissFile(Map<String, Object> params, HttpServletResponse response) {
        Page page = new Page();
        page.setCurrent(0);
        page.setSize(2500);
        PageData<Map> pageData = this.queryPage(params);
        List<Map> list = pageData.getList();
        //list移除集合中entryPic字段等于空的数据
        List<Map<String, Object>> urlList = new ArrayList<>();
        //把list中的entryPic字段不为空的取出来放到urlList中
        Map<String, Object> urlMap = null;
        String file = null;
        for (Map<String, Object> map : list) {
            urlMap = new HashMap<>();
            file = (String) map.get("promissFile");
            if (StringUtils.isBlank(file)) {
                file = "http://img.int-ede.com/ede/20250222/947ab8ed90954ef99420d88b04a7927f.txt";
            }
            urlMap.put("url", file);
            urlMap.put("ticket", map.get("teamName"));
            urlList.add(urlMap);
        }

        if (list.size() > 0) {
            //清空输出流
            response.reset();
            //定义输出类型
            response.setContentType("application/octet-stream");
            String matchId = (String) params.get("matchId");
            SpMatchEntity matchEntity = spMatchService.selectById(matchId);
            // 赛事+筛选条件+参赛证/号码布+月日.zip
            try {
                String title = matchEntity.getMatchName() + "-承诺书" + "-" + DateUtils.format(new Date(), "MMdd") + "-" + list.size() + ".zip";
                // 编译成utf-8格式
                title = URLEncoder.encode(title, "UTF-8");
                response.setHeader("Content-disposition", "attachment;filename=" + title + ";" + "filename*=utf-8''" + title);
                // 打包下载
                ZipUtils.getZipFile(IOUtils.getByte(urlList), response.getOutputStream(), response);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new Result<String>().ok("下载成功");
        } else {
            return new Result<String>().error("没有可下载的数据");
        }
    }

    //全部关闭
    @Override
    public boolean closeAll() {
        List<SpTeamEntity> list = this.baseDao.selectList(
                new QueryWrapper<SpTeamEntity>()
                .eq("is_pass", 1)
                        .or()
                .eq("upd_teacher_flag", 1)
        );
        for (SpTeamEntity teamEntity : list) {
            teamEntity.setIsPass("0");
            teamEntity.setUpdTeacherFlag("0");
            this.baseDao.updateById(teamEntity);
        }
        return true;
    }


}
